package cn.mrlong.base.utils

import android.os.Environment
import android.os.StatFs
import java.io.BufferedReader
import java.io.File
import java.io.IOException
import java.io.InputStreamReader
import java.util.*

/**
 * 作者：BINGO
 * 时间：2021/03/29 11:17
 */
class SDCardUtils private constructor(){
    companion object{
        /**
         * 获取额外的sd卡
         * @return List<String>?
         */
        fun getExtSDCardPathList(): List<String>? {
            val paths: MutableList<String> = ArrayList()
            val extFileStatus = Environment.getExternalStorageState()
            val extFile = Environment.getExternalStorageDirectory()
            //首先判断一下外置SD卡的状态，处于挂载状态才能获取的到
            if (extFileStatus == Environment.MEDIA_MOUNTED && extFile.exists() && extFile.isDirectory
                && extFile.canWrite()
            ) {
                //外置SD卡的路径
                paths.add(extFile.absolutePath)
            }
            try {
                // obtain executed result of command line code of 'mount', to judge
                // whether tfCard exists by the result
                val runtime = Runtime.getRuntime()
                val process = runtime.exec("mount")
                val `is` = process.inputStream
                val isr = InputStreamReader(`is`)
                val br = BufferedReader(isr)
                var line: String? = null
                val mountPathIndex = 1
                while (br.readLine().also { line = it } != null) {
                    // format of sdcard file system: vfat/fuse
                    if (!line!!.contains("fat") && !line!!.contains("fuse") && !line!!.contains("storage")
                        || line!!.contains("secure")
                        || line!!.contains("asec")
                        || line!!.contains("firmware")
                        || line!!.contains("shell")
                        || line!!.contains("obb")
                        || line!!.contains("legacy")
                        || line!!.contains("data")
                    ) {
                        continue
                    }
                    val parts = line!!.split(" ").toTypedArray()
                    val length = parts.size
                    if (mountPathIndex >= length) {
                        continue
                    }
                    val mountPath = parts[mountPathIndex]
                    if (!mountPath.contains("/") || mountPath.contains("data")
                        || mountPath.contains("Data")
                    ) {
                        continue
                    }
                    val mountRoot = File(mountPath)
                    if (!mountRoot.exists() || !mountRoot.isDirectory
                        || !mountRoot.canWrite()
                    ) {
                        continue
                    }
                    val equalsToPrimarySD = mountPath == extFile.absolutePath
                    if (equalsToPrimarySD) {
                        continue
                    }
                    //扩展存储卡即TF卡或者SD卡路径
                    paths.add(mountPath)
                }
            } catch (e: IOException) {
                e.printStackTrace()
            }
            return paths
        }

        /**
         * 判断SDCard是否可用
         *
         * @return
         */
        fun isSDCardEnable(): Boolean {
            return Environment.getExternalStorageState() ==
                    Environment.MEDIA_MOUNTED
        }

        /**
         * 获取SD卡路径
         *
         * @return
         */
        fun getSDCardPath(): String {
            return (Environment.getExternalStorageDirectory().absolutePath
                    + File.separator)
        }

        /**
         * 获取SD卡的剩余容量 单位byte
         *
         * @return
         */
        fun getSDCardAllSize(): Long {
            if (isSDCardEnable()) {
                val stat = StatFs(getSDCardPath())
                // 获取空闲的数据块的数量
                val availableBlocks = stat.availableBlocks.toLong() - 4
                // 获取单个数据块的大小（byte）
                val freeBlocks = stat.availableBlocks.toLong()
                return freeBlocks * availableBlocks
            }
            return 0
        }

        /**
         * 获取指定路径所在空间的剩余可用容量字节数，单位byte
         *
         * @param filePath
         * @return 容量字节 SDCard可用空间，内部存储可用空间
         */
        fun getFreeBytes(filePath: String): Long {
            // 如果是sd卡的下的路径，则获取sd卡可用容量
            var filePath = filePath
            filePath = if (filePath.startsWith(getSDCardPath())) {
                getSDCardPath()
            } else { // 如果是内部存储的路径，则获取内存存储的可用容量
                Environment.getDataDirectory().absolutePath
            }
            val stat = StatFs(filePath)
            val availableBlocks = stat.availableBlocks.toLong() - 4
            return stat.blockSize * availableBlocks
        }

        /**
         * 获取系统存储路径
         *
         * @return
         */
        fun getRootDirectoryPath(): String? {
            return Environment.getRootDirectory().absolutePath
        }
    }
}